package server

import (
	"context"
	"crypto/sha256"
	"fmt"
	"gin/model"
	"gin/model/database"
	"mime/multipart"
	"net/http"
	"path"
	"regexp"
	"runtime"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/robfig/cron/v3"
)

const (
	SuccessCode = 0 //通用成功 状态码
	ErrorCode   = 1 //通用错误 状态码

	LoginExpiredCode = -1 //用户鉴权失败
)

// Response 通用响应
type Response struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data,omitempty"`
}

var Log chan *model.Log

func Init() {
	Log = make(chan *model.Log, 200)

}

// Success 通用成功返回
func Success(c *gin.Context, msg string, data interface{}) {
	Return(c, SuccessCode, msg, data)
}

// Error 通用失败返回
func Error(c *gin.Context, msg string) {
	c.Set("error", msg)
	Return(c, ErrorCode, msg, nil)
}

// Return 通用返回
func Return(c *gin.Context, code int, msg string, data interface{}) {
	r := &Response{
		Code: code,
		Msg:  msg,
		Data: data,
	}
	Json(c, r)
}

// Json 通用json返回
func Json(c *gin.Context, r *Response) {
	c.JSON(http.StatusOK, r)
}

// 手机号正则验证
func VerifyPhone(phone string) bool {
	pattern := `^1[3-9]\d{9}$`
	re := regexp.MustCompile(pattern)
	if !re.MatchString(phone) {
		return false
	}
	return true
}

// 密码加密方法
func PasswordEncryption(pwd string) (string, error) {
	hash := sha256.Sum256([]byte(pwd))
	encryptedPwd := fmt.Sprintf("%x", hash[:])[:32]
	return encryptedPwd, nil
}

/*
缓存key
缓存数据
缓存时间  秒
*/
func RedisSet(key string, data string, times int) error {
	err := database.RedisClient.Set(context.Background(), key, data, time.Duration(times)*time.Second).Err()
	if err != nil {
		fmt.Printf("redis Set失败: %v\n", err)
		return err
	}
	return nil
}
func RedisGet(key string) any {
	data := database.RedisClient.Get(context.Background(), key)
	return data
}

// 设置cookie
func Setcookie(c *gin.Context) {
	cookie := http.Cookie{
		Name:   "session_id",
		Value:  "some_random_value",
		Path:   "/",
		MaxAge: 3600,
	}
	//设置cookie
	http.SetCookie(c.Writer, &cookie)
}

// 文件上传
// 单文件上传
func FileUpload(file *multipart.FileHeader, c *gin.Context) string {
	var dst string
	dst = path.Join("./static/upload", file.Filename)
	_ = c.SaveUploadedFile(file, dst)

	return dst
}

func WriteLog() {
	for {
		select {
		case log, ok := <-Log:
			if !ok {
				fmt.Println("日志通道已关闭，存储协程退出")
				return
			}
			database.DB.Model(model.Log{}).Create(&log)
		}
	}
}
func LogError(format string, v ...interface{}) {
	text := fmt.Sprintf(format, v...)
	now := time.Now()
	fullTime := now.Format("2006-01-02 15:04:05")
	_, file, line, _ := runtime.Caller(1)
	address := fmt.Sprintf("%s:%d", file, line)
	LogTextData := model.Log{}
	LogTextData.Time = fullTime
	LogTextData.Text = text
	LogTextData.Address = address
	LogTextData.LogType = "error"
	Log <- &LogTextData
}
func LogInfo(format string, v ...interface{}) {
	text := fmt.Sprintf(format, v...)
	now := time.Now()
	fullTime := now.Format("2006-01-02 15:04:05")
	_, file, line, _ := runtime.Caller(1)
	address := fmt.Sprintf("%s:%d", file, line)
	LogTextData := model.Log{}
	LogTextData.Time = fullTime
	LogTextData.Text = text
	LogTextData.Address = address
	LogTextData.LogType = "info"
	Log <- &LogTextData
}
func Timing() {

	c := cron.New(cron.WithSeconds())
	c.AddFunc("0 0 16 * * ?", func() {
		fmt.Println("开始删除前一天日志------------------------------")
		// 3. 清理前一天数据（time字段格式：YYYY-MM-DD...）
		yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
		database.DB.Exec("DELETE FROM log WHERE time LIKE ?", yesterday+"%")
		fmt.Printf("已清理 %s 的数据\n", yesterday)
	})
	// 启动任务
	c.Start()
	defer c.Stop()
	select {} // 保持程序运行
}
